home *** CD-ROM | disk | FTP | other *** search
- ; Bitmap rotation engine, v2.0
- ; by Maple Leaf, 22 Oct 96
- ;
- ; Version works for 320x200 bitmaps
- ; --------------------------------------------------------------------------
- ; This is far from being a masterpiece of optimized code; only the jumps and
- ; memory-ADD were optimized a little bit, but anyway, enjoy it.
- ; Note: The bitmap is supposed to be at 320x200, otherwise, the result will
- ; be at least messy...
- ; Some VERY important speed optimizations can be performed if the
- ; bitmap is 256x256... The inner loop would be in this case VERY MUCH
- ; simpler and much faster!
- ; --------------------------------------------------------------------------
- ; asm rules, yup yup! the others suck!
-
- .model TPascal
- .386
- .DATA
-
- extrn _Ax_ : DWORD
- extrn _Ay_ : DWORD
- extrn _Bx_ : DWORD
- extrn _By_ : DWORD
- extrn _Cx_ : DWORD
- extrn _Cy_ : DWORD
- extrn vScr:WORD
- extrn Img:DWORD
- extrn Angle:BYTE
- extrn WW:DWORD
- extrn WH:DWORD
- extrn CosTab:DWORD
- extrn SinTab:DWORD
-
- .CODE
-
- public GenFrame
-
- include jumps.inc
-
- ;****************************************************************************
-
- proc ComputeFramePara near
-
- mov al,Angle
- movzx si,al
- add al,64 ; Angle+90 in a 360-deg system
- movzx di,al
-
- shl si,2
- shl di,2 ; indexes in SinTab/CosTab
-
- mov eax,WH
- xor edx,edx
- mov ecx,dword ptr CosTab[si]
- imul ecx
- shrd eax,edx,8
- add eax,_Ax_ ; eax = _ax_ + WH * cos (angle)
- mov _Bx_,eax ; store result
-
- mov eax,WH
- xor edx,edx
- mov ecx,dword ptr SinTab[si]
- imul ecx
- shrd eax,edx,8
- sub eax,_Ay_
- neg eax ; eax = _ay_ - WH * sin (angle)
- mov _By_,eax ; store result
-
- mov eax,WW
- xor edx,edx
- mov ecx,dword ptr CosTab[di]
- imul ecx
- shrd eax,edx,8
- add eax,_Ax_ ; eax = _ax_ + WW * cos (angle+90)
- mov _Cx_,eax ; store result
-
- mov eax,WW
- xor edx,edx
- mov ecx,dword ptr SinTab[di]
- imul ecx
- shrd eax,edx,8
- sub eax,_Ay_
- neg eax ; eax = _ay_ - WW * sin (angle+90)
- mov _Cy_,eax ; store result
-
- mov eax,_Cx_
- sub eax,_Ax_
- shl eax,16
- cdq
- mov ecx,320
- idiv ecx ; hAdvX = ((_cx_-_ax_) shl 16) div 320
- mov dword ptr cs:smc1+2,eax ; SMCODE INIT
-
- mov eax,_Cy_
- sub eax,_Ay_
- shl eax,16
- cdq
- mov ecx,320
- idiv ecx ; hAdvY = ((_cy_-_ay_) shl 16) div 320
- mov dword ptr cs:smc2+3,eax ; SMCODE INIT
-
- mov eax,_Bx_
- sub eax,_Ax_
- shl eax,16
- cdq
- mov ecx,200
- idiv ecx ; vAdvX = ((_bx_-_ax_) shl 16) div 200
- mov dword ptr cs:smc3+2,eax ; SMCODE INIT
-
- mov eax,_By_
- sub eax,_Ay_
- shl eax,16
- cdq
- mov ecx,200
- idiv ecx ; vAdvY = ((_by_-_ay_) shl 16) div 200
- mov dword ptr cs:smc4+3,eax ; SMCODE INIT
-
- retn
- endp
-
- ;****************************************************************************
-
- e5: add eax,1400000h
- jmp short ce5
-
- e6: add ebx,0C80000h
- jmp short ce6
-
- e7: sub eax,1400000h
- jmp short ce7
-
- e8: sub ebx,0C80000h
- jmp short ce8
-
- GenFrame PROC NEAR ;-----------------------------------------------------
-
- push ds es
-
- ; pushad ; in my example I don't need such sober instructions... :)
- ; but if the registers are vital to your application, feel
- ; free to erase the comment (see POPAD, too!)
-
- call ComputeFramePara
-
- mov es,vScr
- xor di,di
-
- mov eax,_Ax_ ; starting coordinates
- mov ebx,_Ay_ ;
-
- shl eax,16 ; float emulation ...
- shl ebx,16 ;
-
- mov ds,Img[2] ; bitmap seg (from this point on)
-
- ;-- Loop 1 (200 times) ------------------------------------------------------
- mov cx,200
-
- Loop1: push cx eax ebx
-
- ;-- Loop 2 (320 times) ------------------------------------------------------
- mov cx,320
- Loop2: mov esi,ebx
- shr esi,16
-
- ; add si,si
- ; mov si,word ptr RowOffs[si] ; require DS=DATA !!!
-
- mov dx,si ; it seems quite unlikely, but these instructions
- shl si,6 ; are faster than the two instructions above
- shl dx,8 ; (which were replaced)
- add si,dx ;
-
- mov edx,eax
- shr edx,16
- add si,dx
-
- ; mov dl,[si]
- ; mov es:[di],dl
- ; inc di
-
- mov al,[si] ; this combination seems to be faster than two
- stosb ; MOVs and one INC, although it fucks up AL reg.
-
- smc1: add eax,12345678h ;hAdvX ; AL is fucked up, but what the heck...
- sjl e5
- ce5:
- smc2: add ebx,12345678h ;hAdvY
- sjl e6
-
- ce6: cmp eax,1400000h
- sjge e7
-
- ce7: cmp ebx,0C80000h
- sjge e8
-
- ce8: dec cx
- sjg Loop2
-
- ;-- End loop 2 --------------------------------------------------------------
-
- pop ebx eax cx
-
- smc3: add eax,12345678h ;vAdvX
- sjl e1
- ce1:
- smc4: add ebx,12345678h ;vAdvY
- sjl e2
-
- ce2: cmp eax,1400000h
- sjge e3
-
- ce3: cmp ebx,0C80000h
- sjge e4
-
- ce4: dec cx
- sjg Loop1
-
- ;-- End loop 1---------------------------------------------------------------
-
- ; popad
-
- pop es ds
-
- retn
-
- e1: add eax,1400000h
- jmp short ce1
-
- e2: add ebx,0C80000h
- jmp short ce2
-
- e3: sub eax,1400000h
- jmp short ce3
-
- e4: sub ebx,0C80000h
- jmp short ce4
-
- endp
-
-
-
- END
-